#ifndef LOGGER_H
#define LOGGER_H
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <mutex>
#include <memory>
#include <iomanip>
#include <ctime>
#include <filesystem>
#include <QDebug>
#include <QLoggingCategory>
#include "Utility.h"

#define MainPath "master"
//#define MainPath "/home/czh/newProjiect/intelli-eye-label-analysis"

extern bool g_logTrackEnabled;

#define LogTrackq if (g_logTrackEnabled) qDebug()
#define LogTrack if (g_logTrackEnabled) LogDebug
#define LogDebug Logger::getInstance().debug()
#define LogInfo Logger::getInstance().info()
#define LogWarning Logger::getInstance().warning()
#define LogError Logger::getInstance().error()
#define LogFatal Logger::getInstance().fatal()


enum class LogLevel {
    Debug,
    Info,
    Warning,
    Error,
    Fatal
};
class QtLogStream : public std::streambuf {
public:
    QtLogStream(QtMsgType type) : msgType(type) {}

protected:
    int overflow(int c) override {
        if (c != EOF) {
            buffer += static_cast<char>(c);
            if (c == '\n') {
                switch (msgType) {
                case QtDebugMsg:
                    qDebug() << QString::fromStdString(buffer);
                    break;
                case QtInfoMsg:
                    qInfo()<< QString::fromStdString(buffer);
                    break;
                case QtWarningMsg:
                    qWarning()<< QString::fromStdString(buffer);
                    break;
                case QtCriticalMsg:
                    qCritical() << QString::fromStdString(buffer);
                    break;
                default:
                    break;
                }
                buffer.clear();
            }
        }
        return c;
    }

private:
    QtMsgType msgType;
    std::string buffer;
};

class LogStream {
public:
    explicit LogStream(LogLevel level);
    ~LogStream();

    template <typename T>
    LogStream& operator<<(const T& value) {
        buffer << value;
        return *this;
    }

    LogStream& operator<<(std::ostream& (*pf)(std::ostream&)) {
        buffer << pf;
        return *this;
    }

    LogStream& operator<<(const QString& value) {
        buffer << value.toStdString();  // 将 QString 转换为 std::string
        return *this;
    }

private:
    LogLevel logLevel;
    std::ostringstream buffer;
};

class Logger : public QObject {
    Q_OBJECT
    Q_PROPERTY(bool isLogTarck READ isLogTarck WRITE setisLogTarck  NOTIFY isLogTarckChanged)
    Q_PROPERTY(int signalThreshold READ signalThreshold WRITE setsignalThreshold NOTIFY signalThresholdChanged)

public:
    static Logger& getInstance();
    void setLogDirectory(const std::string& directory);
    void log(LogLevel level, const std::string& message);

    LogStream debug() { return LogStream(LogLevel::Debug); }
    LogStream info() { return LogStream(LogLevel::Info); }
    LogStream warning() { return LogStream(LogLevel::Warning); }
    LogStream error() { return LogStream(LogLevel::Error); }
    LogStream fatal() { return LogStream(LogLevel::Fatal); }

    void rotateLogs(const std::string& directory, size_t maxFiles);
    void installQtMessageHandler();

    bool isLogTarck() {return g_logTrackEnabled;};
    void setisLogTarck(bool isLogTarck){
        g_logTrackEnabled = isLogTarck;
        LogDebug << "g_logTrackEnabled :" << g_logTrackEnabled;};


    int signalThreshold() const {return signalThreshold_;};
    void setsignalThreshold(int signalThreshold);

    std::string getCurrentMMTimeStamp();
signals:
    void signalThresholdChanged();
    void isLogTarckChanged();
    //0 debug 1 info 2 warning 3 error 4 fatal
    void logOutputSignal(int level,QString detail);


private:
    int signalThreshold_ = 1;


    Logger(QObject *parent = nullptr);
    ~Logger();
    void openLogFile();
    std::string getCurrentTimeStamp();
    std::string logFileName;
    std::ofstream logFile;
    std::mutex mtx;
    const size_t maxLogSize = 10 * 1024 * 1024; // 10MB
    std::string logDirectory = "master/logs/"; // 默认目录为当前目录
    const int logmaxFiles = 5 ;

    // 禁用复制构造和赋值操作符
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;
    static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
    void writeLog(LogLevel level, const std::string& message);
};

int testLogger();
#endif // LOGGER_H
